use crate::EventHandle;
use std::any::Any;
use std::collections::{HashMap, VecDeque};
use std::sync::Arc;
use tokio::sync::RwLock;

#[derive(Default)]
pub struct Context {
    pub map: Arc<RwLock<HashMap<String, Box<dyn Any + Send + Sync>>>>,
    //非线程安全
    inner: VecDeque<Arc<dyn EventHandle>>,
}

impl Clone for Context {
    fn clone(&self) -> Self {
        return Self {
            map: self.map.clone(),
            inner: self.inner.clone(),
        };
    }
}

impl Context {
    pub async fn store<K: ToString, V: Any + Send + Sync>(&self, key: K, value: V) {
        let key = key.to_string();
        let value = Box::new(value);
        let mut writer = self.map.write().await;
        writer.insert(key, value);
    }
    pub async fn load<V: Any>(&self, key: &str) -> Option<V> {
        let mut writer = self.map.write().await;

        if !writer.get(key)?.is::<V>() {
            return None;
        }
        let val = writer.remove(key)?;
        Some(force_box_to_var(val))
    }
    pub fn unsafe_store_handle(&self, mut hs: VecDeque<Arc<dyn EventHandle>>) {
        let inner = &self.inner;
        unsafe {
            let inner = &mut *(inner as *const VecDeque<Arc<dyn EventHandle>>
                as *mut VecDeque<Arc<dyn EventHandle>>);
            inner.append(&mut hs);
        }
    }
    pub fn unsafe_pop_handle(&self) -> Option<Arc<dyn EventHandle>> {
        let inner = &self.inner;
        unsafe {
            let inner = &mut *(inner as *const VecDeque<Arc<dyn EventHandle>>
                as *mut VecDeque<Arc<dyn EventHandle>>);
            inner.pop_front()
        }
    }
}
fn force_box_to_var<A: ?Sized, T>(any: Box<A>) -> T {
    let any = Some(any);
    unsafe {
        let opt =
            &mut *(&any as *const Option<Box<A>> as *const Option<Box<T>> as *mut Option<Box<T>>);
        let result = std::ptr::replace(opt, None);
        match result {
            None => panic!("force_box_to_var failed"),
            Some(s) => return *s,
        }
    }
}
